package com.unlcn.ils.crsc.api.util;

import com.alibaba.fastjson.JSON;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.unlcn.ils.crsc.api.vo.RestVO;
import com.unlcn.ils.crsc.dao.model.crsc.CrscOtd;
import com.unlcn.ils.crsc.dao.model.crsc.CrscOtdQueryLog;
import com.unlcn.ils.crsc.service.crsc.CrscOTDQueryLogService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * AOP拦截浏览信息
 */
@Aspect
@Component
public class QueryLogInterceptConfig {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private CrscOTDQueryLogService crscOTDQueryLogService;

    @Pointcut("@annotation(com.unlcn.ils.crsc.service.annotation.QueryLogRecorder)")
    public void queryAspect() {

    }

    ThreadLocal<CrscOtdQueryLog> queryThreadLocal = new ThreadLocal<>();

    /**
     * 请求执行前拦截
     * @param joinPoint
     */
    @Before(value = "queryAspect()")
    public void methodBefore(JoinPoint joinPoint){
        Object[] args = joinPoint.getArgs();
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        if(args != null && args.length >0){
            Date now = new Date();
            String vinStrs = String.valueOf(args[0]);
            logger.info("记录查询条件：{0}",vinStrs);
            CrscOtdQueryLog crscOtdQueryLog = new CrscOtdQueryLog();
            crscOtdQueryLog.setParameters(vinStrs);
            crscOtdQueryLog.setQuerySystem("ERP");
            crscOtdQueryLog.setQueryStartTime(now);
            crscOtdQueryLog.setPullOrPush("1");

            // 获取请求客户端的ip
            String ip = getIpAddress(request);
            if(!Strings.isNullOrEmpty(ip)){
                crscOtdQueryLog.setQueryUrl(ip);
            }

            queryThreadLocal.set(crscOtdQueryLog);

        }
    }

    /**
     * 请求执行后拦截
     * @param restVO
     */
    @AfterReturning(returning = "restVO",pointcut = "queryAspect()")
    public void methodAfterReturing(RestVO restVO ){

        int code = restVO.getCode();
        Object data = restVO.getData();

        List<CrscOtd> listCrscOtds = Lists.newArrayList();
        if(!Objects.isNull(data)){
            listCrscOtds = (List<CrscOtd>) data;
        }

        try{
            CrscOtdQueryLog crscOtdQueryLog = queryThreadLocal.get();
            crscOtdQueryLog.setQueryEndTime(new Date());

            if(code == 0){
                crscOtdQueryLog.setSuccess(true);
                crscOtdQueryLog.setResultCount(listCrscOtds.size());
                crscOtdQueryLog.setResultContent(JSON.toJSONString(listCrscOtds));
                crscOtdQueryLog.setMessageCode("200");
                crscOtdQueryLog.setMessage("查询成功");
            }
            else{
                crscOtdQueryLog.setSuccess(false);
                crscOtdQueryLog.setResultCount(0);
                crscOtdQueryLog.setMessageCode("400");
                crscOtdQueryLog.setMessage("查询失败");
            }

            crscOTDQueryLogService.insert(crscOtdQueryLog);

        }
        catch (Exception ex){
            logger.error("methodAfterReturing ERROR Message : {} ", ex.getMessage());
        }
    }

    /**
     * 获取请求客户端IP
     * @param request
     * @return
     */
    private String getIpAddress(HttpServletRequest request){
        String ipAddress = request.getHeader("x-forwarded-for");
        if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("Proxy-Client-IP");
        }
        if (ipAddress == null || ipAddress.length() == 0 || "unknow".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getRemoteAddr();
            if(ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")){
                // 根据网卡获取本机配置的IP地址
                InetAddress inetAddress = null;
                try {
                    inetAddress = InetAddress.getLocalHost();
                } catch (UnknownHostException e) {
                    logger.error("QueryLogInterceptConfig.getIpAddress {}", e);
                    return null;
                }
                ipAddress = inetAddress.getHostAddress();
            }
        }
        // 对于通过多个代理的情况，第一个IP为客户端真实的IP地址，多个IP按照','分割
        if(null != ipAddress && ipAddress.length() > 15){
            if(ipAddress.indexOf(",") > 0){
                ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
            }
        }

        return ipAddress;
    }

}
